﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using personalplaner.viewmodels;
using System.Threading;
using personalplaner.common.threading;
using personalplaner.common.utilities.controls;

namespace personalplaner
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            loadingIndicator.Child = CreateMediaElementOnWorkerThread();
            SizeChanged += new SizeChangedEventHandler(MainWindowSizeChanged);
        }

        /// <summary>
        /// Handle the system window commands for window minimize, maximize, restore and close
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
		private void OnSystemWindowCommandExecute(object sender, ExecutedRoutedEventArgs e)
		{
			if (e.Command == Microsoft.Windows.Shell.SystemCommands.CloseWindowCommand)
				Microsoft.Windows.Shell.SystemCommands.CloseWindow((Window)e.Parameter);
			if (e.Command == Microsoft.Windows.Shell.SystemCommands.MaximizeWindowCommand)
				Microsoft.Windows.Shell.SystemCommands.MaximizeWindow((Window)e.Parameter);
			if (e.Command == Microsoft.Windows.Shell.SystemCommands.RestoreWindowCommand)
				Microsoft.Windows.Shell.SystemCommands.RestoreWindow((Window)e.Parameter);
			if (e.Command == Microsoft.Windows.Shell.SystemCommands.MinimizeWindowCommand)
				Microsoft.Windows.Shell.SystemCommands.MinimizeWindow((Window)e.Parameter);
		}

		private void MainWindowLoaded(object sender, RoutedEventArgs e)
		{
			var dc = DataContext as MainWindowViewModel;
			if (dc == null)
				return;

			dc.Load();

            StopWait();
		}

        void MainWindowSizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (waitIndicator == null)
                return;

            //loadingIndicator.Width = e.NewSize.Width;
            //loadingIndicator.Height = e.NewSize.Height;

            //loadingIndicator.UpdateLayout();

            //waitIndicator.Dispatcher.Invoke(new Action(delegate()
            //{
            //    //waitIndicator.Width = e.NewSize.Width;
            //    //waitIndicator.Height = e.NewSize.Height;
            //    waitIndicator.Width = ActualWidth;
            //    waitIndicator.Height = ActualHeight;

            //    waitIndicator.UpdateLayout();
            //}));

        }

		public void StartWait()
		{
			if (loadingIndicator.Child == null)
				loadingIndicator.Child = CreateMediaElementOnWorkerThread();

            if (waitIndicator == null)
                return;

            loadingIndicator.Width = ActualWidth;
            loadingIndicator.Height = ActualHeight;

            waitIndicator.Dispatcher.Invoke(new Action(delegate()
            {
                waitIndicator.Visibility = System.Windows.Visibility.Visible;

                waitIndicator.Width = ActualWidth;
                waitIndicator.Height = ActualHeight;
                
                waitIndicator.UpdateLayout();
            }));
		}

		public void StopWait()
		{
            if (waitIndicator == null)
                return;

            waitIndicator.Dispatcher.Invoke(new Action(delegate()
            {
                waitIndicator.Visibility = System.Windows.Visibility.Collapsed;
            }));

            //loadingBackground.SetVisibility(System.Windows.Visibility.Collapsed);
		}


        /// <summary>
        /// circular progressbar
        /// </summary>
        FrameworkElement waitIndicator;
        
		private HostVisual CreateMediaElementOnWorkerThread()
		{
			// Create the HostVisual that will "contain" the VisualTarget
			// on the worker thread.
			HostVisual hostVisual = new HostVisual();

            // Spin up a worker thread, and pass it the HostVisual that it
			// should be part of.
            Thread thread = new Thread(new ParameterizedThreadStart(MediaWorkerThread));
			thread.SetApartmentState(ApartmentState.STA);
			thread.IsBackground = true;
			thread.Start(hostVisual);

			// Wait for the worker thread to spin up and create the VisualTarget.
			s_event.WaitOne();

			return hostVisual;
		}

		private FrameworkElement CreateMediaElement()
		{
            //waitIndicator = new ProgressIndicator()
            //{
            //    IsRunning = true,
            //    IsIndeterminate = true,
            //    //Width=Double.NaN,
            //    //Height=Double.NaN
            //    //HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
            //    //VerticalAlignment = System.Windows.VerticalAlignment.Stretch
            //};

            //waitIndicator = new MediaElement();
            //waitIndicator.BeginInit();
            //((MediaElement)waitIndicator).Source = new Uri("http://download.microsoft.com/download/2/C/4/2C433161-F56C-4BAB-BBC5-B8C6F240AFCC/SL_0410_448x256_300kb_2passCBR.wmv?amp;clcid=0x409");
            //waitIndicator.Width = 200;
            //waitIndicator.Height = 100;
            //waitIndicator.EndInit();

            waitIndicator = new CircularLoadingWait()
            {
                Height = this.ActualHeight,
                Width = this.ActualWidth,
                //Visibility = System.Windows.Visibility.Collapsed,
                //HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
                //VerticalAlignment = System.Windows.VerticalAlignment.Stretch
            };

            //waitIndicator = new Border()
            //{
            //    BorderBrush = Brushes.Orange,
            //    BorderThickness = new Thickness(5),
            //    Background = Brushes.PaleGreen,
            //    Opacity = 0.5
            //};

            waitIndicator.UpdateLayout();

			return waitIndicator;
		}

		private void MediaWorkerThread(object arg)
		{
			// Create the VisualTargetPresentationSource and then signal the
			// calling thread, so that it can continue without waiting for us.
			var hostVisual = (HostVisual)arg;
			var visualTargetPS = new VisualTargetPresentationSource(hostVisual);
			s_event.Set();
            
			// Create a MediaElement and use it as the root visual for the
			// VisualTarget.
			visualTargetPS.RootVisual = CreateMediaElement();

			// Run a dispatcher for this worker thread.  This is the central
			// processing loop for WPF.
			System.Windows.Threading.Dispatcher.Run();
		}

		private static AutoResetEvent s_event = new AutoResetEvent(false);
    }
}
